package sy6_Behavioral_Pattern.observer.ext;
/*
 * 观察者模式研究观察目标和观察者两类对象之间的一对多关系
 * 考虑一个借款方（Debit）与多个放款方（Credit）的情形
 * 约定：借款方资金充足时，通知所有放款方，连本带息结清。
 */
import java.util.ArrayList;
import java.util.List;

interface Debit{  //借款方接口（抽象借款方）
	public void  borrow(Credit credit); //借钱
	public void notifyCredits();  //向所有放款方发消息
}

interface Credit{  //放款方接口（抽象放款方）
	public void takeMoney(Debit debit); //借款方通知放款方拿钱
}

class ConcreteDebit implements Debit{   //具体借款方
	
	private String name;   //借款人姓名
	private List<Credit>allCredits=new ArrayList<Credit>();  //维护一个放款方集合
	
	public ConcreteDebit(String name) {  //构造方法
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	
	@Override
	public void borrow(Credit credit) {  //借款人向放款人借钱
		allCredits.add(credit);  //添加放款方至集合
	}

	@Override
	public void notifyCredits() {
		//调用接口方法takeMoney()；广而告之的内容就是借款方收到的内容
		allCredits.forEach(credit->credit.takeMoney(new ConcreteDebit(name)));  //函数式编程（Lambda表达式）
	}
}

class ConcreteCredit implements Credit{   //具体放款方
	private String name;  //放款人姓名
	
	public ConcreteCredit(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}

	@Override
	public void takeMoney(Debit debit) {  //接口类型的方法参数 
		System.out.println(name+"收到通知："+((ConcreteDebit)debit).getName()+"连本带息还我款");
	}
}

public class Client {
	public static void main(String[] args) {
		//创建一个具体借款人
		ConcreteDebit zhangsan = new ConcreteDebit("张三");
		
		//借款人与放款人之间的一对多关系
		zhangsan.borrow(new ConcreteCredit("李四"));
		zhangsan.borrow(new ConcreteCredit("王五"));
		zhangsan.borrow(new ConcreteCredit("赵六"));
		
		//借款人向所有放款人发布还款通知
		zhangsan.notifyCredits();
	}
}
